package com.iceflame.zxingane.funs;

import java.util.Collection;

import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import com.adobe.fre.FREArray;
import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREObject;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.iceflame.zxingane.EventType;
import com.iceflame.zxingane.ZXingAne;

public class SycDecode implements FREFunction {
	
	private Queue<Img> queue = new ConcurrentLinkedQueue<SycDecode.Img>();

	@Override
	public FREObject call(FREContext arg0, FREObject[] arg1) {
		if(arg1.length == 0){
			return null;
		}
		try{
			Img img = new Img();
			img.width = arg1[0].getAsInt();
			img.height = arg1[1].getAsInt();
			FREArray array = (FREArray)arg1[2];
			long len = array.getLength();
			img.pixels = new int[(int) len];
			for(int i = 0 ; i < len ; i++){
				img.pixels[i] = array.getObjectAt(i).getAsInt();
			}
			queue.add(img);
			
			if(!runThread.isAlive()){
				runThread.start();
			}
		}catch(Exception e){
			String errStr = e.getMessage();
	        ZXingAne.dispatchEvent(EventType.ERROR, "SycDecodeCatchError:" + errStr);
		}
		return null;
	}
	
	public class Img{
		
		public int width = 0;
		
		public int height = 0;
		
		public int[] pixels = null;
		
	}
	
	
	private Thread runThread = new Thread(new Runnable() {
		
		@Override
		public void run() {
			String str = null;
			String type = null;
			try{
				long time = System.currentTimeMillis();
				ZXingAne.dispatchEvent(EventType.DEBUG, "StartSycEncode");
				
				Img img = queue.poll();
				if(img == null){
					try{
						Thread.sleep(1000);
					}catch(Exception e){}
				}
				ZXingAne.dispatchEvent(EventType.DEBUG, "type0");
				int width = img.width;
				int height = img.height;
				int[] pixels = img.pixels;
				ZXingAne.dispatchEvent(EventType.DEBUG, "type1");
				Map<DecodeHintType,Object> hints = new HashMap<DecodeHintType, Object>();
				Collection<BarcodeFormat> decodeFormats = EnumSet.noneOf(BarcodeFormat.class);
				decodeFormats.addAll(EnumSet.of(BarcodeFormat.QR_CODE));
				hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
				hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
				RGBLuminanceSource rgbsource = new RGBLuminanceSource(width, height, pixels);
				HybridBinarizer hybrid = new HybridBinarizer(rgbsource);
				BinaryBitmap binBitmap = new BinaryBitmap(hybrid);
				Result lResult = new MultiFormatReader().decode(binBitmap, hints);
				long timeUse = System.currentTimeMillis() - time;
				ZXingAne.dispatchEvent(EventType.DEBUG,"SycDecodeComplete,Use:" + timeUse);
				str = lResult.getText();
				type = lResult.getBarcodeFormat().name();
			}catch(Exception e){
				String errStr = e.getMessage();
		        ZXingAne.dispatchEvent(EventType.ERROR, "SycDecodeCatchError: " + errStr);
			}
			if(str != null || type != null){
				ZXingAne.dispatchEvent(EventType.DECODE,str + "=%|%=" + type);
			}else{
				ZXingAne.dispatchEvent(EventType.DECODE,"null");
			}
		}
	});

}
